package com.bena.udvtui2;

import java.util.*;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.location.*;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;

import com.google.android.maps.*;

public class ShowMap extends MapActivity {
	private static final String PROXIMITY_INTENT_ACTION = new String("com.bena.udvt2.action.PROXIMITY_ALERT");
	private LocationManager locManager;
	private MyLocationListener listener;
	private MyLocationOverlay mLocOverlay;
	private ProximityAlertReceiver receiver;
	private String provider;
	private IntentFilter mIntentFilter;
	private ArrayList<LatLonPair> mPositions;
	private List<Vector<String>> randInfo;
	SQLiteDatabase myDatabase;
	MediaRecorder audioListener;
	MediaPlayer player;

	int changeView = 0;
	private MapView mapView;
	int seenLocs;
	String[] cs = null;
	String tempString;
	String temp; // used for seen=1
	String othertempString;

	int seen=0;
	int seenLoc=0;

	public static ImageButton goInfoButton;
	public static String proxName;

	@Override  // override the back button to call finish
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK)) {
			Log.d(this.getClass().getName(), "back button pressed");
			Bundle bundle = new Bundle();
			bundle.putStringArray("seen",cs);
			bundle.putInt("count", seenLocs);
			Intent resultIntent = new Intent();
			resultIntent.putExtras(bundle);
			setResult(Activity.RESULT_OK, resultIntent);
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent intent){
		// This is for when an activity completes.  Requires startAcitivtyForResult(string,int);
		//Toast.makeText(ShowMap.this, "reqC: "+requestCode+" resC: "+resultCode, Toast.LENGTH_SHORT).show();
		if(requestCode==UDVirtualTourUI.INFO_PAGE_RESULT && resultCode==-1){ 
			Log.e("ActivityResult","loading");
			Bundle bundle2 = intent.getExtras();
			seenLocs = bundle2.getInt("count");
			cs = bundle2.getStringArray("seen");
			Log.d("SHOWMAP_RESUME","result:"+seenLocs);
			for(int i=0; i<seenLocs;i++){  // print everything in the array
				Log.d("SHOWMAP_SEEN",cs[i]);
			}
		}
		else if(requestCode==UDVirtualTourUI.MAP_PAGE_RESULT && resultCode==0){
			//UDVirtualTourUI.this.finishActivity(MAP_PAGE_RESULT);
		}
		else{
			Log.e("ActivityResult","fail");
		}
	}

	@Override
	public void onSaveInstanceState(Bundle savedInstanceState){
		Bundle bundle = new Bundle();
		bundle.putStringArray("seen", cs);
		bundle.putInt("count", seenLocs);
		savedInstanceState.putBundle("bundle", bundle);
		super.onSaveInstanceState(savedInstanceState);
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void onCreate(Bundle savedInstanceState){
		Log.d("SHOWMAP","onCreate");
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
		setContentView(R.layout.map);

		/* DATA TRANSFER START */
		Intent myIntent = getIntent();  // get the intent sent to the Activity
		Bundle bundle = new Bundle();
		//final String newString;
		bundle=myIntent.getBundleExtra("bundle");  // get the bundle from the intent
		cs=bundle.getStringArray("seen");
		Log.d("SHOWMAP_SEEN_LENGTH",""+seenLocs);
		seenLocs=bundle.getInt("count");
		for(int i=0; i<seenLocs;i++){  // print everything in the array
			Log.d("SHOWMAP_SEEN",cs[i]);
		}
		/* DATA TRANSFER COMPLETE */
	    randInfo = new randomSounds().getData();
		if (player!=null)
			player.release();
		if (player == null) {
			player = new MediaPlayer ();
		}

		mapView = (MapView)findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		final ToggleButton streetViewBtn = (ToggleButton) findViewById(R.id.StreetOrSatellite);
		//mapView.setBuiltInZoomControls(true);

		streetViewBtn.setOnClickListener(new OnClickListener() {
			public void onClick(View view)
			{
				if (streetViewBtn.isChecked())
				{
					mapView.setSatellite(true);
					mapView.setStreetView(false);
				}
				else
				{
					mapView.setSatellite(false);
					mapView.setStreetView(true);
				}        
			}
		});

		goInfoButton = (ImageButton) findViewById(R.id.inRangeButton);
		goInfoButton.setVisibility(View.INVISIBLE);

		goInfoButton.setOnClickListener(new View.OnClickListener(){
			public void onClick(View v) {
				Intent intent = new Intent("com.bena.udvtui2.infopage");
				Bundle bundle = new Bundle();
				seen=0;
				Log.d("SHOWMAP_prox","proxName="+proxName);
				for(int i=0; i<seenLocs; i++){
					if(cs[i]==proxName){
						seen=1;
						temp = cs[i];
						cs[i]=cs[seenLocs-1];
						cs[seenLocs-1]=temp;
						Log.d("SHOWMAP_prox","Seen");
						break;
					}
				}
				if(seen==0){
					Log.d("SHOWMAP_prox","not seen");
					cs[seenLocs]=proxName;
					seenLocs++;
				}
				else{
					Log.d("SHOWMAP_prox","seen working");
					tempString = cs[seenLocs-1];
					cs[seenLocs-1]=proxName;
					cs[seenLoc]=tempString;
				}	
				Log.d("SHOWMAP_prox","proxName complete");
				bundle.putStringArray("seen",cs);
				Log.d("SHOWMAP_prox","loaded cs");
				bundle.putInt("count", seenLocs);
				Log.d("SHOWMAP_prox","loaded seenLocs");
				intent.putExtra("bundle", bundle);
				Log.d("SHOWMAP_prox","loaded bundle");
				//Log.d("MAIN: START","start activity");
				Log.d("SHOWMAP_prox","Starting activity for result");
				startActivityForResult(intent,com.bena.udvtui2.UDVirtualTourUI.INFO_PAGE_RESULT);
			}
		});


		// Location Stuff

		receiver = new ProximityAlertReceiver();    
		listener = new MyLocationListener();        
		locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
		provider = LocationManager.GPS_PROVIDER;

		locManager.requestLocationUpdates(
				provider, 
				600000, 
				0.5f,
				listener
		);

		/*
		 * According to javadoc, best values for min time to check for updates is greater than 
		 * 60,000 ms.  This means that it will only check for updates every 60 seconds, which is not bad.
		 * I think we should keep this number really high, and use the min location as delimiter for when
		 * we should request an update. E.g
		 * requestLocationUpdates(provider, 10000000000, 10, listener)
		 */

		mIntentFilter = new IntentFilter(PROXIMITY_INTENT_ACTION);
		registerReceiver(receiver, mIntentFilter);
		createPositions();
		registerIntents();
		initMapView();
		mLocOverlay.enableMyLocation();
	}

	protected void onResume() {  // need to re-render map locations with less transparency
		super.onResume();
		Log.d("SHOWMAP_RESUME","onResume");
		mapView.invalidate();
		player = new MediaPlayer ();
		playRandomSound();
		initMapView();
		//Toast.makeText(ShowMap.this, "invalidating", Toast.LENGTH_SHORT).show();
		mLocOverlay.enableMyLocation();
		registerReceiver(receiver, mIntentFilter);
	}

	protected void onDestroy(){
		Bundle bundle = new Bundle();
		bundle.putStringArray("seen",cs);
		bundle.putInt("count", seenLocs);
		Intent resultIntent = new Intent();
		resultIntent.putExtras(bundle);
		setResult(Activity.RESULT_OK, resultIntent);
		super.onDestroy();

		mLocOverlay.disableMyLocation();
		unregisterReceiver(receiver);
		locManager.removeUpdates(listener);
		//locManager=null;
		//listener=null;
	}
	protected void onFinish(){
		Bundle bundle = new Bundle();
		bundle.putStringArray("seen",cs);
		bundle.putInt("count", seenLocs);
		Intent resultIntent = new Intent();
		resultIntent.putExtras(bundle);
		setResult(Activity.RESULT_OK, resultIntent);
		super.finish();

		mLocOverlay.disableMyLocation();
		unregisterReceiver(receiver);
		locManager.removeUpdates(listener);
		//locManager=null;
		//listener=null;
	}
	protected void onPause(){
		super.onPause();
		player.stop();
		player.release();
		mLocOverlay.disableMyLocation();
	}

	private void createPositions() {
		myDatabase = openOrCreateDatabase( "/mnt/sdcard/UDVT/UDVirtualTour.db", SQLiteDatabase.CREATE_IF_NECESSARY, null); 
		Cursor c = myDatabase.query("UDVirtualTour", null, null, null, null, null, null);
		c.moveToFirst();
		mPositions = new ArrayList<LatLonPair>();

		for(int i = 0;i<c.getCount();i++){
			Log.e("POSITIONS",c.getString(1) + " " + c.getDouble(2)/100000000 + " " + c.getDouble(3)/100000000);
			mPositions.add(new LatLonPair(c.getString(1), c.getDouble(2)/100000000, c.getDouble(3)/100000000));
			c.moveToNext();
		}
		c.close();

	}

	private void registerIntents() {
		Log.v("UDVT2", "In registerIntents");
		for(int i = 0; i < mPositions.size(); i++) {
			Log.v("UDVT2", "registerIntents: i is " + i);
			LatLonPair latLon = mPositions.get(i);
			setProximityAlert(latLon.getName(), latLon.getLatitude(), latLon.getLongitude(), i+1, i);
		}
	}

	private void setProximityAlert(String name, double lat, double lon, final long eventID, int requestCode)
	{
		// 5 meter radius
		float radius = 5f;

		Intent intent = new Intent(PROXIMITY_INTENT_ACTION);
		intent.putExtra(ProximityAlertReceiver.EVENT_ID_INTENT_EXTRA, eventID);
		intent.putExtra("name", name);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);

		locManager.addProximityAlert(lat, lon, radius, -1, pendingIntent);
	}

	private void initMapView() {
		mapView = (MapView) findViewById(R.id.mapview);
		mLocOverlay = new MyLocationOverlay(getApplicationContext(), mapView);
		List<Overlay> overlays = mapView.getOverlays();
		overlays.clear();
		overlays.add(mLocOverlay);

		mapView.setBuiltInZoomControls(true);

		addPositionOverlays();

		MapController mc = (MapController) mapView.getController();
		mc.animateTo((new LatLonPair(39.680699, -75.7514124)).getGeoPoint());
		mc.setZoom(19);
	}

	private void addPositionOverlays() {
		Log.d("POS","adding positions");
		Drawable defaultMarker = getResources().getDrawable(R.drawable.new_map_marker);
		defaultMarker.setBounds(0, 0, defaultMarker.getIntrinsicWidth(), defaultMarker.getIntrinsicHeight());
		OverlayList overlayList = new OverlayList(defaultMarker);

		Drawable seenMarker = getResources().getDrawable(R.drawable.new_map_marker_seen3);
		seenMarker.setBounds(0, 0, seenMarker.getIntrinsicWidth(), seenMarker.getIntrinsicHeight());
		OverlayList seenOverlayList = new OverlayList(seenMarker);
		for(int i = 0; i < mPositions.size(); i++) {
			LatLonPair latLon = mPositions.get(i);
			Log.d("LATLON",""+latLon.getName()+" == "+cs[i]);
			//Log.d("LATLON","seen: " + seenLocs);
			for(int j=0; j<seenLocs; j++){
				Log.d("LATLON",""+latLon.getName()+" == "+cs[j]);
				othertempString=latLon.getName();
				if(othertempString.contains(cs[j])){
					latLon.seen=1;
					//Log.d("LATLON","has been seen");
				}
			}
			latLon.setLatitude(latLon.getLatitude()-0.0001);
			//latLon.setLongitude(latLon.getLongitude());
			OverlayItem overlay = new OverlayItem(latLon.getGeoPoint(), "Title "+i, "Snippet "+1);
			latLon.setLatitude(latLon.getLatitude()+0.0001);
			//latLon.setLongitude(latLon.getLongitude());
			if(latLon.seen==0){
				Log.d("LATLON","not seen");
				overlayList.add(overlay);
			}
			else{
				Log.d("LATLON","seen");
				seenOverlayList.add(overlay);
			}
		}
		List<Overlay> overlays = mapView.getOverlays();
		overlays.add(overlayList);
		overlays.add(seenOverlayList);
	}

	class MyLocationListener implements LocationListener {
		public void onLocationChanged(Location location) {
			Log.d("LOCCHANGE", "Location changed");
			//playRandomSound();
			mLocOverlay.enableMyLocation(); // redraws mLocOverlay
		}
		public void onProviderDisabled(String provider) {}
		public void onProviderEnabled(String provider) {}
		public void onStatusChanged(String provider, int status, Bundle extras) { }
	}

	public void playRandomSound(){
		if(player.isPlaying()==false){
			player.setVolume(100,100);
			Log.d("AUDIO_PATH","size: "+randInfo.size());
			if(randInfo.size()==0){
				randInfo = new randomSounds().getData();
				Log.d("AUDIO_PATH","resetting");
			}
			Log.d("AUDIO_PATH","current: "+randInfo.get(0).get(0));
			String audioFilePath = randInfo.get(0).get(0);
			randInfo.remove(0);
			Log.d("AUDIO",audioFilePath );
			try {
				Log.d("AUDIO","Beginning Play");
				player.setDataSource(audioFilePath);
				player.prepare();	
				player.start();	
			} catch (Exception e) {
				Log.e("AUDIO", "Playback failed.", e);
			}
			Log.d("AUDIO","play passed MAP" );
		}
	}
}

